package cn.zzq.aix.nativeinterface.classproxy;
import java.lang.reflect.Method;

import com.google.appinventor.components.annotations.DesignerComponent;
import com.google.appinventor.components.annotations.SimpleFunction;
import com.google.appinventor.components.annotations.SimpleObject;
import com.google.appinventor.components.annotations.UsesLibraries;
import com.google.appinventor.components.common.ComponentCategory;
import com.google.appinventor.components.runtime.AndroidNonvisibleComponent;
import com.google.appinventor.components.runtime.ComponentContainer;
import com.google.appinventor.components.runtime.util.YailList;
import com.google.appinventor.components.runtime.util.YailProcedure;

import leo.android.cglib.proxy.Enhancer;
import leo.android.cglib.proxy.MethodInterceptor;
import leo.android.cglib.proxy.MethodProxy;

@DesignerComponent(version = 0, //
		category = ComponentCategory.EXTENSION, //
		description = "代理器", //
		nonVisible = true, //
		iconName = "images/extension.png")
@SimpleObject(external = true)
@UsesLibraries(libraries="cglib-for-android.jar")
public class ClassProxyer extends AndroidNonvisibleComponent {

	public ClassProxyer(ComponentContainer container) {
		super(container.$form());
	}

	@SimpleFunction
	public Object CreateInstanceBySuperClass(Class<?> superClass, YailProcedure interceptCallback) {
		Enhancer e = new Enhancer(form);
		e.setSuperclass(superClass);
		e.setInterceptor(new MethodInterceptor() {

			@Override
			public Object intercept(Object object, Object[] args, MethodProxy methodProxy) throws Exception {
				return interceptCallback.call(object, YailList.makeList(args), methodProxy);
			}
		});
		return e.create();
	}

	@SimpleFunction
	public String GetMethodName(MethodProxy methodProxy) {
		return methodProxy.getMethodName();
	}

	@SimpleFunction
	public Object InvokeSuperMethod(Object object, YailList argsValue, MethodProxy methodProxy) {
		return methodProxy.invokeSuper(object, argsValue.toArray());
	}

	@SimpleFunction
	public Method GetOriginalMethod(MethodProxy methodProxy) {
		return methodProxy.getOriginalMethod();
	}

	@SimpleFunction
	public Method GetProxyMethod(MethodProxy methodProxy) {
		return methodProxy.getProxyMethod();
	}

}
